package com.hd123.rumba.qt.result;

import java.io.IOException;
import java.util.Date;
import java.util.Hashtable;

import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.exception.StringTooLongException;
import com.hd123.rumba.qt.def.IQueryDefinitionMgr;
import com.hd123.rumba.qt.def.ParseException;
import com.hd123.rumba.qt.def.QueryDefinition;
import com.hd123.rumba.qt.def.SQLCheckList;
import com.hd123.rumba.qt.run.QueryThread;
import com.hd123.rumba.runtime.NamingMgr;
import com.hd123.rumba.runtime.Persistent;
import com.hd123.rumba.util.StringUtil;

public class QueryResultDescription extends Persistent {

  public void setQuery(QueryDefinition query) {
    this.query = query;
    queryCriteria.setQuery(query);
    displayCriteria.setQuery(query);
  }

  /**
   * 根据params设置查询条件和显示条件.<br>
   * 
   * @param params
   */
  public void setCriteria(Hashtable params) {
    if (params != null) {
      queryCriteria.setCriteria(params);
      displayCriteria.setCriteria(params);
      query.setCriteria(queryCriteria.getSg());
    }
    query.getOrders().clear(); // 清除order条件, 从源数据库中查询时不需要排序
    try {
      String info = this.getInfo();
      if (info != null)
        this.queryCriteriaInfo = StringUtil.truncate(getInfo(), 255, true);
      else
        this.queryCriteriaInfo = null;
    } catch (StringTooLongException e) {
    }
  }

  /**
   * 返回一个hashtable, 其内容为当前设置的条件, 满足setCriteria的参数要求.<br>
   * 
   * 将当前条件sg构造成一个hashtable, 第0行是条件名称.<br>
   * 如果没有当前条件, 则按查询定义的默认条件.<br>
   * 如果第i个条件有候选值列表, 则hashtable中有qtQueryPickName_i.number,
   * qtQueryPickValue_i.number两个entry<br>
   * 返回值例如<br>
   * qtQuery_0.0=供应商代码类似于<br>
   * qtQuery_0.1=单号在之中<br>
   * qtQuery_0.2=货品代码在之中<br>
   * qtQuery_1.0=V1<br>
   * qtQuery_1.1=<br>
   * qtQuery_1.2=A1,A2<br>
   * qtQuery_2.0=<br>
   * qtQuery_2.1=<br>
   * qtQuery_2.2=<br>
   * qtQuery_3.0=<br>
   * qtQuery_3.1=<br>
   * qtQuery_3.2=<br>
   * qtQueryPickName_1.0=单号名称0<br>
   * qtQueryPickValue_1.0=单号值0<br>
   * qtQueryPickName_1.1=单号名称1<br>
   * qtQueryPickValue_1.1=单号值1<br>
   * qtSortColumn_0=aa<br>
   * qtSortOrder_0=asc<br>
   * qtSortColumn_1=bb<br>
   * qtSortOrder_1=desc<br>
   * 其中, qtQuery_后的数字是行.列, 行之间表示or关系, 每列对应一个条件.<br>
   * qtQueryPickName_, qtQueryPickValue后的数字是列.序号, 列对应一个条件<br>
   * qtSortColumn_, qtSortOrder_后的数字是序号
   * 
   * @return
   */
  public Hashtable getCriteria() throws Exception {
    Hashtable h = new Hashtable();
    h.putAll(queryCriteria.getCriteria());
    h.putAll(displayCriteria.getCriteria());
    return h;
  }

  /**
   * 返回查询条件的文本, 包括预设条件
   * 
   * @return
   * @throws ParseException
   * @throws BusinessException
   * @throws IOException
   */
  public String getInfo() {
    try {
      // 预设条件
      StringBuffer sb = new StringBuffer();
      QueryDefinition query = getQuery();
      if (query == null) {
        IQueryDefinitionMgr qdm = (IQueryDefinitionMgr) NamingMgr.getInstance().lookupMgr(
            IQueryDefinitionMgr.class);
        query = qdm.getQueryDefinition(this);
        setQuery(query);
      }
      SQLCheckList scl = query.getChecks();
      String[] checks = getQueryCriteria().getSg()[5];
      for (int j = 0; j < scl.getCaptions().size(); j++) {
        if ("yes".equals((String) checks[j])
            && !((String) scl.getExpressions().get(j)).startsWith(":")) {
          if (scl.getAndOr().trim().equals("and"))
            sb.append("并且");
          else
            sb.append("或者");
          sb.append(scl.getCaptions().get(j));
        }
      }
      // 条件
      return queryCriteria.getInfo() + sb.toString();
    } catch (Throwable e) {
      return "此查询结果无效.";
    }
  }

  public String debugInfo() {
    StringBuffer sb = new StringBuffer();
    sb.append(getClass().getName() + "\n");
    sb.append("qdName=" + qdName + "\n");
    sb.append("qdTime=" + qdTime + "\n");
    sb.append("userUuid=" + getUserUuid() + "\n");
    sb.append("startTime=" + startTime + "\n");
    sb.append("timeUsed=" + timeUsed + "\n");
    sb.append("resultCount=" + resultCount + "\n");
    sb.append("threadId=" + threadId + "\n");
    sb.append("queryCriteria=" + (queryCriteria == null ? null : queryCriteria.debugInfo()) + "\n");
    sb.append("displayCriteria=" + (displayCriteria == null ? null : displayCriteria.debugInfo())
        + "\n");
    sb.append("query=" + (query == null ? null : query.debugInfo()) + "\n");
    return sb.toString();
  }

  private transient QueryDefinition query;
  private String qdUuid;
  private String qdName;
  private Date qdTime;
  private String userUuid;
  private Date startTime;
  private Long timeUsed;
  private Integer resultCount;
  private Long threadId;
  private QueryThread queryThread;
  private QueryCriteria queryCriteria = new QueryCriteria();
  private DisplayCriteria displayCriteria = new DisplayCriteria();
  private String message;
  private String queryCriteriaInfo;

  public String getMessage() {
    return message;
  }

  public void setMessage(String message) {
    try {
      if (message != null)
        message = StringUtil.truncate(message, 1000, true);
    } catch (StringTooLongException e) {
    }
    this.message = message;
  }

  public DisplayCriteria getDisplayCriteria() {
    return displayCriteria;
  }

  public void setDisplayCriteria(DisplayCriteria displayCriteria) {
    this.displayCriteria = displayCriteria;
  }

  public String getQdName() {
    return qdName;
  }

  public void setQdName(String qdName) {
    this.qdName = qdName;
  }

  public Date getQdTime() {
    return qdTime;
  }

  public void setQdTime(Date qdTime) {
    this.qdTime = qdTime;
  }

  public QueryDefinition getQuery() {
    return query;
  }

  public QueryCriteria getQueryCriteria() {
    return queryCriteria;
  }

  public void setQueryCriteria(QueryCriteria queryCriteria) {
    this.queryCriteria = queryCriteria;
  }

  public Integer getResultCount() {
    return resultCount;
  }

  public void setResultCount(Integer resultCount) {
    this.resultCount = resultCount;
  }

  public Date getStartTime() {
    return startTime;
  }

  public void setStartTime(Date startTime) {
    this.startTime = startTime;
  }

  public Long getThreadId() {
    return threadId;
  }

  public void setThreadId(Long threadId) {
    this.threadId = threadId;
  }

  public QueryThread getQueryThread() {
    return queryThread;
  }

  public void setQueryThread(QueryThread queryThread) {
    this.queryThread = queryThread;
  }

  public Long getTimeUsed() {
    return timeUsed;
  }

  public void setTimeUsed(Long timeUsed) {
    this.timeUsed = timeUsed;
  }

  public String getUserUuid() {
    return userUuid;
  }

  public void setUserUuid(String userUuid) {
    this.userUuid = userUuid;
  }

  public String getTableName() {
    return "qt" + getUuid().substring(getUuid().length() - 20);
  }

  public String getResultCountString() {
    if (getResultCount() == null) {
      return "&nbsp;";
    } else if (RESULTCOUNT_CANCEL.equals(getResultCount())) {
      return "取消";
    } else if (RESULTCOUNT_RUNNING.equals(getResultCount())) {
      return "正在执行";
    } else if (RESULTCOUNT_ERROR.equals(getResultCount())) {
      return "错误";
    } else {
      return getResultCount().toString();
    }
  }

  public static final Integer RESULTCOUNT_RUNNING = new Integer(-1);
  public static final Integer RESULTCOUNT_ERROR = new Integer(-2);
  public static final Integer RESULTCOUNT_CANCEL = new Integer(-3);

  public final static String CAPTION_QDNAME = "查询名称";
  public final static String CAPTION_STATE = "状态";
  public final static String CAPTION_STARTTIME = "开始时间";
  public final static String CAPTION_TIMEUSED = "执行时间";
  public final static String CAPTION_RESULTCOUNT = "记录数";
  public final static String CAPTION_QUERYCRCRITERIA = "查询条件";
  public final static String CAPTION_USER = "用户";

  public String getQdUuid() {
    return qdUuid;
  }

  public void setQdUuid(String qdUuid) {
    this.qdUuid = qdUuid;
  }

  public String getQueryCriteriaInfo() {
    return queryCriteriaInfo;
  }

  public void setQueryCriteriaInfo(String queryCriteriaInfo) {
    this.queryCriteriaInfo = queryCriteriaInfo;
  }

}
